from dataclasses import dataclass
from dataclasses_json import dataclass_json
from SkyOfficeLint.models import *
from typing import Callable, Literal, Tuple


@dataclass_json
@dataclass
class CheckerReport:
    # cls
    type: Literal["warning", "error"]
    description: str
    page_range: Tuple[int, int]
    text: str

    def conv_page_range(self):
        if self.page_range[0] == self.page_range[1]:
            return f"{self.page_range[0]}"
        else:
            return f"{self.page_range[0]}~{self.page_range[1]}"

    def truncate_text(self):
        LENGTH = 100
        return self.text if len(self.text) <= LENGTH else self.text[:LENGTH] + "..."

    def to_str(self):
        return (
            f"{self.type.upper()}: {self.description}，位于第 {self.conv_page_range()} 页。\n"
            f"该段内容：{self.truncate_text()}\n"
        )


def checker_report_factory(
    type: Literal["warning", "error"], desc: str
) -> Callable[..., CheckerReport]:
    def wrapper(paragraph: ParagraphInfo, *args, **kwargs):
        return CheckerReport(
            type,
            description=desc.format(*args, **kwargs),
            page_range=paragraph.page_range.to_tuple(),
            text=paragraph.text,
        )

    return wrapper


class CheckerReports:
    class ParagraphFormatError:
        class Indentation:
            INDENT_FIRST_LINE_WITH_SPACE = checker_report_factory(
                "error", "使用空格符代替首行缩进格式"
            )
            INDENT_FIRST_LINE_WITH_TAB = checker_report_factory(
                "error", "使用制表符(TAB)代替首行缩进格式"
            )
            INDENT_UNIT_NOT_MATCH = checker_report_factory(
                "error", "缩进单位“{0}”与规定的缩进单位“{1}”不一致"
            )

        class Font:
            INVALID_FONT = checker_report_factory("error", "不合规的字体——“{0}”")
